﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using BugNET.UserInterfaceLayer;
using BugNET.Common;
using BugNET.BLL;
using BugNET.Entities;
using BugNET.BLL.Comparers;
using System.Text;

namespace BugNET.WikiPages.UserControls
{
    public partial class WikiPageList : System.Web.UI.UserControl, IEditProjectControl
    {
        //*********************************************************************
        //
        // This user control is used by both the new project wizard and update
        // project page.
        //
        //*********************************************************************

        Project CurrentProject;

        /// <summary>
        /// Gets or sets the project id.
        /// </summary>
        /// <value>The project id.</value>
        public int ProjectId
        {
            get { return Convert.ToInt16(Session["ProjectId"]); }
            set { Session["ProjectId"] = value; }
        }

        /// <summary>
        /// Gets or sets the wikiPageId
        /// </summary>
        /// <value>The wikiPageId.</value>
        int wikiPageId
        {
            get { return Convert.ToInt16(Session["wikiPageId"]); }
            set { Session["wikiPageId"] = value; }
        }

        public string currentPageName
        {
            get { return ViewState.Get("currentPageName", string.Empty); }
            set { ViewState.Set("currentPageName", value); }
        }


        /// <summary>
        /// Gets or sets the sort field.
        /// </summary>
        /// <value>The sort field.</value>
        string SortField
        {
            get { return ViewState.Get("SortField", "SortOrder"); }
            set { ViewState.Set("SortField", value); }
        }

        /// <summary>
        /// Gets or sets a value indicating whether [sort ascending].
        /// </summary>
        /// <value><c>true</c> if [sort ascending]; otherwise, <c>false</c>.</value>
        bool SortAscending
        {
            get { return ViewState.Get("SortAscending", true); }
            set { ViewState.Set("SortAscending", value); }
        }

        /// <summary>
        /// Gets or sets the wikiId
        /// </summary>
        /// <value>The wikiId.</value>
        int wikiId
        {
            get { return Convert.ToInt16(Session["wikiId"]); }
            set { Session["wikiId"] = value; }
        }

        /// <summary>
        /// Handles the Load event of the Page control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        protected void Page_Load(object sender, EventArgs e)
        {

            if (!IsPostBack)
            {
                var page = Page as UserInterfaceLayer.BasePage;

                if (page != null)
                {
                    ProjectId = page.ProjectId;
                }
                //ProjectId = Request.QueryString.Get("pid", 0);
                // If don't know project or issue then redirect to something missing page
                if (ProjectId == 0)
                    ErrorRedirector.TransferToSomethingMissingPage(Page);

                CurrentProject = ProjectManager.GetById(ProjectId);

                if (CurrentProject == null)
                {
                    ErrorRedirector.TransferToNotFoundPage(Page);
                    return;
                }

                //security check: add issue
                if (!UserManager.HasPermission(ProjectId, Common.Permission.AddIssue.ToString()))
                {
                    ErrorRedirector.TransferToLoginPage(Page);
                }
                BindWikiPages();

                wikiId= 0; // reset wikiId value
            }
        }

        /// <summary>
        /// Updates this instance.
        /// </summary>
        /// <returns></returns>
        public bool Update()
        {
            return Page.IsValid;
        }


        /// <summary>
        /// Inits this instance.
        /// </summary>
        public void Initialize()
        {

        }

        /// <summary>
        /// Binds the status.
        /// </summary>
        void BindWikiPages()
        {
            grdVwWikiPages.Columns[1].HeaderText = "Page Name";
            grdVwWikiPages.Columns[2].HeaderText = "Created By";
            grdVwWikiPages.Columns[3].HeaderText = "Created On";

            string SearchText = txtSearchText.Text;

            var dswikiPages = WikiManager.GetWikiPageDetails(ProjectId, SearchText);
            if (dswikiPages.Count == 0)
            {
                divNoRecords.InnerHtml = GenerateNoRecordsHTML();
                divNoRecords.Visible = true;
                grdVwWikiPages.Visible = false;
                pager.Visible = false;
                return;
            }
            else
            {
                divNoRecords.Visible = false;
                grdVwWikiPages.Visible = true;
                pager.Visible = true;
            }
            dswikiPages.Sort(new WikiPageComparer(SortField, SortAscending));

            grdVwWikiPages.DataSource = dswikiPages;
            grdVwWikiPages.DataBind();
        }

        /// <summary>
        /// Gets a value indicating whether [show save button].
        /// </summary>
        /// <value><c>true</c> if [show save button]; otherwise, <c>false</c>.</value>
        public bool ShowSaveButton
        {
            get { return false; }
        }

        /// <summary>
        /// Adds the status.
        /// </summary>
        /// <param name="s">The s.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected void AddWikiPage(Object s, EventArgs e)
        {
            var newPageName = txtPageName.Text.Trim();

            if (!isValidPageName(newPageName))
                return;

            var newWikiPage = new Wiki { ProjectId = ProjectId, WikiPageName = newPageName, UserCreated = Security.GetUserName() };
            int resultValue = 0;
            WikiManager.SaveWikiPageDetails(newWikiPage, ref resultValue);

            if (resultValue > 0)
            {
                txtPageName.Text = string.Empty;
                BindWikiPages();
            }
            else
            {
                ActionMessage.ShowErrorMessage(LoggingManager.GetErrorMessageResource("SaveIssueTypeError"));
            }
        }

        public void SearchWikiPageName(Object s, EventArgs e)
        {
            if (txtSearchText.Text == string.Empty)
                return;
            panelSearchResultsFor.Visible = true;
            ltrlSearchResultsfor.Text = "Search results for: \" <B>" + txtSearchText.Text + "</B>\"  \t                                 ";
            BindWikiPages();

        }

        public void ClearSearchWikiPageName(Object s, EventArgs e)
        {
            txtSearchText.Text = string.Empty;
            panelSearchResultsFor.Visible = false;
            BindWikiPages();
        }


        protected void grdWikiPageDetails_SortCommand(object source, DataGridSortCommandEventArgs e)
        {
            SortField = e.SortExpression;
            BindWikiPages();
        }

        protected void grdVwWikiPageDetails_RowDataBound(object sender, GridViewRowEventArgs e)
        {

            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                var currentWikiPage = (Wiki)e.Row.DataItem;

                var lblIssueTypeName = (LinkButton)e.Row.FindControl("lnkPageName");
                if (lblIssueTypeName != null)
                {
                    lblIssueTypeName.Text = currentWikiPage.WikiPageName;
                    lblIssueTypeName.CommandArgument = Convert.ToString(currentWikiPage.WikiPageId);
                    // lblIssueTypeName.NavigateUrl = "../../WikiPages/ShowWiki.aspx?pid=" + ProjectId + "&wikiPageId=" + currentWikiPage.WikiPageId;
                }

                var lblPageCreatedBy = (Label)e.Row.FindControl("lblCreatedBy");
                if (lblPageCreatedBy != null)
                    lblPageCreatedBy.Text = currentWikiPage.UserCreated;

                var lblPageCreatedOn = (Label)e.Row.FindControl("lblCreatedOn");
                if (lblPageCreatedOn != null)
                    lblPageCreatedOn.Text = currentWikiPage.DateCreated.ToShortDateString();

                var lblSortOrder = (Label)e.Row.FindControl("lblSortOrder");
                if (lblSortOrder != null)
                    lblSortOrder.Text = currentWikiPage.SortOrder.ToString();

                var cmdDelete = (ImageButton)e.Row.FindControl("cmdDelete");
                var message = string.Format(GetLocalResourceObject("ConfirmDelete").ToString(), currentWikiPage.WikiPageName);
                if (cmdDelete != null)
                    cmdDelete.Attributes.Add("onclick", String.Format("return confirm('{0}');", message.JsEncode()));

                var txtIssueTypeName = (TextBox)e.Row.FindControl("txtWikiPageName");
                if (txtIssueTypeName != null)
                    txtIssueTypeName.Text = currentWikiPage.WikiPageName;
            }


        }

        /// <summary>
        /// Handles the Sorting event of the grdVwWikiPages control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="T:System.Web.UI.WebControls.GridViewSortEventArgs"/> instance containing the event data.</param>
        protected void grdVwWikiPages_Sorting(object sender, GridViewSortEventArgs e)
        {
            SortField = e.SortExpression;
            SortAscending = !SortAscending;
            var dswikiPages = WikiManager.GetWikiPageDetails(ProjectId, txtSearchText.Text);
            dswikiPages.Sort(new WikiPageComparer(SortField, SortAscending));
            grdVwWikiPages.DataSource = dswikiPages;
            grdVwWikiPages.SortField = e.SortExpression;
            e.SortDirection = SortDirection.Descending;
            grdVwWikiPages.DataBind();

            for (var i = 0; i < grdVwWikiPages.Columns.Count - 1; i++)
            {
                var tc = grdVwWikiPages.HeaderRow.Cells[i];
                if (!tc.HasControls()) continue;

                // search for the header link  
                var lnk = tc.Controls[0] as LinkButton;

                if (lnk == null) continue;

                Image sortImage = new Image();
                if (tc.Controls.Count > 1)
                    sortImage = tc.Controls[1] as Image;
                if (sortImage == null) continue;

                string imgUrl = string.Format("~/images/{0}.png", (SortAscending ? "bullet_arrow_up" : "bullet_arrow_down"));

                // setting the dynamically URL of the image
                // checking if the header link is the user's choice
                if (SortField == lnk.CommandArgument)
                {
                    sortImage.ImageUrl = imgUrl;
                    return;
                }
            }

        }

        /// <summary>
        /// Handles the PageIndexChanging event of the grdVwWikiPages control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="T:System.Web.UI.WebControls.GridViewPageEventArgs"/> instance containing the event data.</param>
        protected void grdVwWikiPages_PageIndexChanging(object sender, GridViewPageEventArgs e)
        {
            grdVwWikiPages.PageIndex = e.NewPageIndex; // needed for server side paging
            BindWikiPages();

        }

        protected void grdVwWikiPages_DataBinding(object sender, EventArgs e)
        {
            var grid = sender as GridView;
        }

        protected void grdVwWikiPages_RowEditing(object sender, GridViewEditEventArgs e)
        {
            foreach (GridViewRow gr in grdVwWikiPages.Rows)
            {
                if (gr.RowIndex == e.NewEditIndex)
                {
                    currentPageName = ((LinkButton)gr.FindControl("lnkPageName")).Text;
                }
            }
            grdVwWikiPages.EditIndex = e.NewEditIndex;
            BindWikiPages();
        }



        private bool isValidPageName(string wikipageName)
        {
            if (wikipageName.Length > 100)
            {
                ActionMessage.ShowErrorMessage(LoggingManager.GetErrorMessageResource("WikiPageNameLengthExceeds"));
                return false;
            }

            List<Wiki> wikiPagelList = WikiManager.GetWikiPageDetails(ProjectId, string.Empty);
            foreach (Wiki item in wikiPagelList)
            {
                if (item.WikiPageName.Trim() == wikipageName)
                {
                    ActionMessage.ShowErrorMessage(LoggingManager.GetErrorMessageResource("DuplicateWikiPageName"));
                    return false;
                }
            }
            return true;
        }
        protected void grdVwWikiPages_RowUpdating(object sender, GridViewUpdateEventArgs e)
        {

            TextBox txtWikiPageName = (TextBox)(grdVwWikiPages.Rows[e.RowIndex].FindControl("txtWikiPageName"));

            if (txtWikiPageName.Text.Trim() == currentPageName.Trim()) // No DB update required
            {
                grdVwWikiPages.EditIndex = -1;
                BindWikiPages();
                return;
            }
            if (!isValidPageName(txtWikiPageName.Text))
                return;

            Wiki currentObject = new Wiki();
            currentObject.ProjectId = ProjectId;
            currentObject.WikiPageId = Convert.ToInt32(grdVwWikiPages.DataKeys[e.RowIndex].Value);
            currentObject.UserCreated = Security.GetUserName();


            currentObject.WikiPageName = txtWikiPageName.Text.Trim();

            Label lblSortOrder = (Label)(grdVwWikiPages.Rows[e.RowIndex].FindControl("lblSortOrder"));
            if (lblSortOrder != null)
                currentObject.SortOrder = Convert.ToInt16(lblSortOrder.Text.Trim());

            int resultValue = 0;
            WikiManager.SaveWikiPageDetails(currentObject, ref resultValue);
            grdVwWikiPages.EditIndex = -1;
            BindWikiPages();
        }

        protected void grdVwWikiPages_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            if (e.CommandName == "Navigate")
            {
                LinkButton lnkbtnPageName = (LinkButton)e.CommandSource;
                wikiPageId = Convert.ToInt16(lnkbtnPageName.CommandArgument);
                Response.Redirect("ShowWiki.aspx");
                return;

            }

            if (e.CommandName != "up" && e.CommandName != "down")
                return;

            ImageButton imgBtn = (ImageButton)e.CommandSource;
            GridViewRow gRow = ((GridViewRow)(imgBtn.Parent.Parent));

            var itemIndex = ((GridViewRow)(imgBtn.Parent.Parent)).RowIndex;
            if (itemIndex < 0) return;
            int resultValue = 0;


            Wiki currentObject = new Wiki();
            currentObject.ProjectId = ProjectId;

            currentObject.WikiPageId = Convert.ToInt32(grdVwWikiPages.DataKeys[gRow.RowIndex].Value);

            var lnkPageName = ((LinkButton)gRow.FindControl("lnkPageName"));
            if (lnkPageName != null)
                currentObject.WikiPageName = lnkPageName.Text.Trim();
            var lblSortOrder = (Label)gRow.FindControl("lblSortOrder");
            if (lblSortOrder != null)
                currentObject.SortOrder = Convert.ToInt32(lblSortOrder.Text.Trim());
            currentObject.UserCreated = Security.GetUserName();

            switch (e.CommandName)
            {
                case "up":
                    //move row up
                    if (itemIndex == 0)
                        return;
                    currentObject.SortOrder -= 1;
                    SortField = "SortOrder";
                    SortAscending = false;
                    WikiManager.SaveWikiPageDetails(currentObject, ref resultValue);
                    BindWikiPages();
                    break;
                case "down":
                    //move row down

                    if (itemIndex == grdVwWikiPages.Rows.Count - 1)
                        return;

                    currentObject.SortOrder += 1;
                    SortField = "SortOrder";
                    SortAscending = false;
                    WikiManager.SaveWikiPageDetails(currentObject, ref resultValue);
                    BindWikiPages();
                    break;


            }


        }

        protected void grdVwWikiPages_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
        {
            grdVwWikiPages.EditIndex = -1;
            BindWikiPages();
        }

        protected void grdVwWikiPages_RowDeleting(object sender, GridViewDeleteEventArgs e)
        {
            int wikiPageId = Convert.ToInt32(grdVwWikiPages.DataKeys[e.RowIndex].Value);
            WikiManager.DeleteWikiPage(wikiPageId);
            BindWikiPages();
        }

        public string GenerateNoRecordsHTML()
        {
            // To approximate uniform display with and without records this GridView HTML is generated.
            StringBuilder strHTML = new StringBuilder();

            strHTML.Append("<table class='grid'>");
            strHTML.Append("<tr class='gridHeader'>");

            strHTML.Append("<th align='right' style='width:45px;' scope='col'>&nbsp;</th><th align='left' scope='col'>Page Name</th>");
            strHTML.Append("<th align='left' scope='col'>Created By</th><th align='left' scope='col'>Created On</th>");
            strHTML.Append("<th align='center' style='width:125px;' scope='col'>Default Sort Order</th><th scope='col'>&nbsp;</th>");
            strHTML.Append("<tr>");
            strHTML.Append("<td align='center' colspan='6'> No records found</td>");
            strHTML.Append("</tr>");

            strHTML.Append("</table>");
            return strHTML.ToString();





        }
    }
}